package hikari.gui.panels;

import com.gooddies.wiring.annotations.PostWiring;
import com.gooddies.wiring.annotations.WiringComponent;
import hikari.instruments.HikariInstrument;

import java.awt.*;
import java.awt.event.*;

/**
 * @author sad
 */
@WiringComponent
public class Main3dPanel extends Canvas {

    private HikariInstrument instrument;
    private int lastX = -1;
    private int lastY = -1;

    private Main3dPanel() {
    }

    @PostWiring
    private void init() {
        initListeners();
    }

    private void initListeners() {
        addMouseWheelListener(new MouseWheelListener() {
            @Override
            public void mouseWheelMoved(MouseWheelEvent e) {
                if (instrument != null) {
                    instrument.mouseWheel(e.getX(), e.getY(), e.getUnitsToScroll(), e.getModifiersEx());
                }
            }
        });

        addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (instrument != null) {
                    int modifiers = e.getModifiersEx();
                    if (e.getButton() == 1) {
                        modifiers = modifiers | MouseEvent.BUTTON1_DOWN_MASK;
                    } else if (e.getButton() == 3) {
                        modifiers = modifiers | MouseEvent.BUTTON3_DOWN_MASK;
                    } else if (e.getButton() == 2) {
                        modifiers = modifiers | MouseEvent.BUTTON2_DOWN_MASK;
                    }
                    if (e.getClickCount() == 2) {
                        instrument.mouseDblClick(e.getX(), e.getY(), e.getButton(), modifiers);
                    } else {
                        instrument.mouseClick(e.getX(), e.getY(), e.getButton(), modifiers);
                    }
                }
            }

            @Override
            public void mousePressed(MouseEvent e) {
                if (instrument != null) {
                    int modifiers = e.getModifiersEx();
                    if (e.getButton() == 1) {
                        modifiers = modifiers | MouseEvent.BUTTON1_DOWN_MASK;
                    } else if (e.getButton() == 3) {
                        modifiers = modifiers | MouseEvent.BUTTON3_DOWN_MASK;
                    } else if (e.getButton() == 2) {
                        modifiers = modifiers | MouseEvent.BUTTON2_DOWN_MASK;
                    }
                    instrument.mouseDown(e.getX(), e.getY(), e.getButton(), modifiers);
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                if (instrument != null) {
                    int modifiers = e.getModifiersEx();
                    if (e.getButton() == 1) {
                        modifiers = modifiers | MouseEvent.BUTTON1_DOWN_MASK;
                    } else if (e.getButton() == 3) {
                        modifiers = modifiers | MouseEvent.BUTTON3_DOWN_MASK;
                    } else if (e.getButton() == 2) {
                        modifiers = modifiers | MouseEvent.BUTTON2_DOWN_MASK;
                    }
                    instrument.mouseUp(e.getX(), e.getY(), e.getButton(), modifiers);
                }
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                lastX = e.getX();
                lastY = e.getY();
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }
        });

        addMouseMotionListener(new MouseMotionListener() {
            @Override
            public void mouseDragged(MouseEvent e) {
                int x = e.getX();
                int y = e.getY();
                int dx = x - lastX;
                int dy = y - lastY;

                if (instrument != null) {
                    instrument.mouseMove(x, y, dx, dy, e.getModifiersEx());
                }
                lastX = x;
                lastY = y;
            }

            @Override
            public void mouseMoved(MouseEvent e) {
                int x = e.getX();
                int y = e.getY();
                int dx = x - lastX;
                int dy = y - lastY;

                if (instrument != null) {
                    instrument.mouseMove(x, y, dx, dy, e.getModifiersEx());
                }
                lastX = x;
                lastY = y;
            }
        });

        addKeyListener(new KeyListener() {
            @Override
            public void keyTyped(KeyEvent e) {
                if (instrument != null) {
                    instrument.keyType(e);
                }
            }

            @Override
            public void keyPressed(KeyEvent e) {
                if (instrument != null) {
                    instrument.keyDown(e);
                }
            }

            @Override
            public void keyReleased(KeyEvent e) {
                if (instrument != null) {
                    instrument.keyUp(e);
                }
            }
        });
    }

    public HikariInstrument getInstrument() {
        return instrument;
    }

    public void setInstrument(HikariInstrument instrument) {
        this.instrument = instrument;
    }

    @SuppressWarnings("deprecation")
    public long getHWND() {
        try {
            Class cl = Class.forName("sun.awt.windows.WComponentPeer");
            java.lang.reflect.Field f = cl.getDeclaredField("hwnd");
            f.setAccessible(true);
            return f.getLong(this.getPeer());
        } catch (ClassNotFoundException | NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
            System.err.println("Fatal Error:");
            return -1;
        }
    }
}
